package com.capgemini.teamtwo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.capgemini.teamtwo.common.BusinessException;
import com.capgemini.teamtwo.common.ExceptionEnum;
import com.capgemini.teamtwo.common.UserConstant;
import com.capgemini.teamtwo.entity.PageRequest;
import com.capgemini.teamtwo.entity.ProjectInfo;
import com.capgemini.teamtwo.entity.ProjectMember;
import com.capgemini.teamtwo.entity.SysUser;
import com.capgemini.teamtwo.entity.dto.ProjectMemberDTO;
import com.capgemini.teamtwo.entity.dto.ProjectUser;
import com.capgemini.teamtwo.entity.dto.ProjectUserQueryDTO;
import com.capgemini.teamtwo.mapper.ProjectMemberMapper;
import com.capgemini.teamtwo.mapper.SysUserMapper;
import com.capgemini.teamtwo.mapper.UserMapper;
import com.capgemini.teamtwo.service.ProjectInfoService;
import com.capgemini.teamtwo.service.ProjectMemberService;
import com.capgemini.teamtwo.service.SysUserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ProjectMemberServiceImpl extends ServiceImpl<ProjectMemberMapper, ProjectMember> implements ProjectMemberService {

    @Autowired
    private  UserMapper userMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private ProjectMemberMapper projectMemberMapper;

    @Autowired
    private SysUserService sysUserService;



    @Override
    public PageInfo<ProjectUser> findByUsername(PageRequest<String> request) {

        //查询条件
        String name = request.getRequest();

        //分页参数
        PageHelper.startPage(request.getNum(),request.getSize());
        //查询符合条件的用户列表
        List<ProjectUser> users = userMapper.findBenchUsersByUsername(name);
        PageInfo<ProjectUser> pageInfo = new PageInfo<>(users);
        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean releaseById(ProjectMemberDTO dto) {

        if (CollectionUtils.isNotEmpty(dto.getUserIds())) {
            // 根据传入ids查询用户信息
            List<SysUser> sysUserList = sysUserMapper.selectBatchIds(dto.getUserIds());

            // 筛选出存在leader的用户
            SysUser leaderUser = sysUserList.stream().filter(user -> user.getRank().equals(UserConstant.PROJECT_LEVEL)).findFirst().orElse(null);

            // 如果leaderUser不为空
            if (!Objects.isNull(leaderUser)) {
                throw new BusinessException(ExceptionEnum.LEADER_UNREALSE);
            }
            // 数据中不存在leader 根据用户id进行人员释放
            sysUserService.updateUserById(dto.getUserIds(), UserConstant.USER_STATUS_BANCH, UserConstant.PROJECT_NUM);

            // 删除 member表中projectId=0的用户
            projectMemberMapper.deleteUserIds(dto.getUserIds());



        }
        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addBatch(ProjectMemberDTO dto) {

        // 验证必传参数
        if (ObjectUtils.isNull(dto.getProjectId())){
            throw new BusinessException(ExceptionEnum.PROJEST_NOT_NULL);
        }

        // 判断人员ids是否为空 为空的话不进行逻辑处理直接返回成功
        if(ObjectUtils.isNull(dto.getUserIds())){
            return true;
        }
        // 如果不为空的话 更新所选人员的user表信息
        sysUserService.updateUserById(dto.getUserIds(),UserConstant.USER_STATUS_ON_PROJECT,dto.getProjectId());

        // member表赋值
        List<ProjectMember> list = new ArrayList<>();
        dto.getUserIds().forEach(id ->{
            ProjectMember projectMember = new ProjectMember();
            projectMember.setMemberId(id);
            projectMember.setProjectId(dto.getProjectId());
            list.add(projectMember);
        });

        // 插入人员与项目的关系绑定
        this.saveBatch(list);



        return true;
    }

    /**
     * 查询项目上的员工列表
     * @param request 分页条件
     * @return
     */
    public PageInfo<ProjectUserQueryDTO> findProjectUsers(PageRequest<ProjectMemberDTO> request){

        ProjectMemberDTO projectMember = request.getRequest();

        //判断参数是否为空
        if (ObjectUtils.isNull(projectMember)||ObjectUtils.isNull(projectMember.getProjectId())){
            throw new BusinessException(ExceptionEnum.PROJEST_NOT_NULL);
        }
        // 根据项目id查询对应的人员信息
        PageHelper.startPage(request.getNum(),request.getSize());
        List<ProjectUserQueryDTO> projectUsers = projectMemberMapper.findProjectUsers(projectMember.getProjectId());

        // 排序 leader排在查询结果前
        this.orderByDept(projectUsers);

        PageInfo<ProjectUserQueryDTO> pageInfo = new PageInfo<>(projectUsers);
        return pageInfo;
    }


    //查询项目人数并保存
//    @Override
//    public void calculateAndUpdate(Integer projectId) {
//        ProjectInfo projectInfo=projectInfoService.getById(projectId);
//        if(projectInfo!=null) {
//            LambdaQueryWrapper<ProjectMember> projectMemberLambdaQueryWrapper = new LambdaQueryWrapper<>();
//            projectMemberLambdaQueryWrapper.eq(ProjectMember::getProjectId, projectInfo.getId());
//            projectInfo.setMemberNumber(this.count(projectMemberLambdaQueryWrapper));
//            projectInfoService.updateById(projectInfo);
//        }
//        return;
//    }

    //按职级排序
    private void orderByDept(List<ProjectUserQueryDTO> projectUsers){

        List<ProjectUserQueryDTO> collect = projectUsers.stream()
                .filter(user -> UserConstant.PROJECT_LEVEL.equals(user.getRank()))
                .collect(Collectors.toList());

        //如果存在leader进入判断，进行重新排序
        if(CollectionUtils.isNotEmpty(collect)) {
            projectUsers.removeAll(collect);
            projectUsers.addAll(collect);
            Collections.reverse(projectUsers);
        }
    }
}
